import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingDeque;

public class ProducerConsumer {
	private static final int BOUND = 16;
	private static final int N_CONSUMERS = 8;

	private static void interruptProducers(List<Thread> indexerPool) {
		for (Thread indexerThread : indexerPool) {
			indexerThread.interrupt();
		}
	}

	public static void startComputation() {
		@SuppressWarnings("unchecked")
		BlockingDeque<Integer>[] dequeues = new BlockingDeque[N_CONSUMERS];

		for (int i = 0; i < dequeues.length; i++) {
			dequeues[i] = new LinkedBlockingDeque<Integer>(BOUND);
		}

		CountDownLatch latch = new CountDownLatch(1);

		int producerIndex = 0;
		Thread producer = new Thread(new Producer(dequeues, latch), "Producer-"
				+ producerIndex);
		producerIndex++;
		producer.start();

		final List<Thread> producerPool = new ArrayList<Thread>();

		for (int i = 0; i < N_CONSUMERS; i++) {
			Thread t = new Thread(new Consumer(dequeues, i), "Consumer-" + i);
			t.start();
			producerPool.add(t);
		}

		try {
			latch.await();
			interruptProducers(producerPool);
		} catch (InterruptedException e) {
			System.out.println("Was interrupted, while awaiting for latch.");
		}
	}
}